from typing import Dict, Optional
from datetime import datetime, timedelta
from loguru import logger
from app.core.config import Settings
from .dahua_service import DahuaService
from .hikvision_service import HikvisionService
from .door_service import DoorService
from .alarm_service import AlarmService

class ServiceManager:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(ServiceManager, cls).__new__(cls)
            cls._instance._initialized = False
        return cls._instance
        
    def __init__(self):
        if self._initialized:
            return
            
        # 初始化服务实例
        self.dahua_service = DahuaService()
        self.hikvision_service = HikvisionService()
        self.alarm_service = AlarmService()
        self.door_service = DoorService(
            dahua_service=self.dahua_service,
            hikvision_service=self.hikvision_service,
            alarm_service=self.alarm_service
        )
        
        # 存储所有门禁设备的状态
        self.door_states: Dict[str, str] = {}
        # 存储人脸识别记录（临时存储，用于匹配刷卡记录）
        self.face_records: Dict[str, dict] = {}
        self._initialized = True
        
    async def initialize(self, settings: Settings):
        """初始化所有服务"""
        try:
            # 初始化大华服务
            await self.dahua_service.initialize(
                api_host=settings.DAHUA_API_HOST,
                app_key=settings.DAHUA_APP_KEY,
                app_secret=settings.DAHUA_APP_SECRET
            )
            
            # 初始化海康服务
            await self.hikvision_service.initialize(
                api_host=settings.HIKVISION_API_HOST,
                app_key=settings.HIKVISION_APP_KEY,
                app_secret=settings.HIKVISION_APP_SECRET
            )
            
            # 订阅事件
            await self._subscribe_events(settings.EVENT_CALLBACK_URL)
            
            # 清空状态
            self.door_states.clear()
            self.face_records.clear()
            
            logger.info("所有服务初始化完成")
        except Exception as e:
            logger.error(f"服务初始化失败: {str(e)}")
            raise
            
    async def _subscribe_events(self, callback_url: str):
        """订阅所有需要的事件"""
        try:
            # 订阅大华门禁刷卡事件
            await self.dahua_service.subscribe_card_events(callback_url)
            # 订阅海康人脸识别事件
            await self.hikvision_service.subscribe_face_events(callback_url)
            logger.info("事件订阅完成")
        except Exception as e:
            logger.error(f"事件订阅失败: {str(e)}")
            raise
            
    async def process_face_event(self, face_data: dict):
        """处理人脸识别事件"""
        door_id = face_data.get("door_id")
        if not door_id:
            logger.error("人脸识别事件缺少door_id")
            return
            
        # 存储人脸识别记录
        self.face_records[door_id] = {
            "data": face_data,
            "timestamp": datetime.now()
        }
        
    async def process_card_event(self, card_data: dict):
        """处理刷卡事件"""
        door_id = card_data.get("door_id")
        if not door_id:
            logger.error("刷卡事件缺少door_id")
            return
            
        # 获取最近的人脸识别记录
        face_record = self._get_valid_face_record(door_id)
        
        if face_record:
            # 处理访问请求
            success = await self.door_service.process_access_request(
                door_id=door_id,
                face_record=face_record["data"],
                card_records=[card_data]
            )
            if success:
                self.update_door_state(door_id, "open")
            else:
                self.update_door_state(door_id, "closed")
            
    def _get_valid_face_record(self, door_id: str) -> Optional[dict]:
        """获取有效的人脸识别记录"""
        record = self.face_records.get(door_id)
        if not record:
            return None
            
        # 检查记录是否在1分钟内
        if datetime.now() - record["timestamp"] > timedelta(minutes=1):
            # 删除过期记录
            del self.face_records[door_id]
            return None
            
        return record
            
    def get_door_state(self, door_id: str) -> Optional[str]:
        """获取门禁状态"""
        return self.door_states.get(door_id)
        
    def update_door_state(self, door_id: str, state: str):
        """更新门禁状态"""
        if not door_id:
            logger.error("更新门禁状态时缺少door_id")
            return
        self.door_states[door_id] = state
        
# 创建服务管理器单例
service_manager = ServiceManager()
